#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <Point3D.h>
#include <osg/Switch>


Point3D::Point3D() : osg::MatrixTransform()
{
    m_radius = 1.0;
    m_fineness = 1;
    m_coordinateSize = 2;
    m_indexInTrajectory3D = 1;
    buildChildNode();
}

Point3D::Point3D(const Point3D & point3D, const osg::CopyOp &copyop) : MatrixTransform(point3D,copyop)
{
}

Point3D::~Point3D()
{

}

double Point3D::getRadius()
{
    return m_radius;
}

double Point3D::getFineness()
{
    return m_fineness;
}

double Point3D::getCoordinateSize()
{
    return m_coordinateSize;
}

bool Point3D::getShowShpere()
{
    return m_switch->getValue(0);
}

bool Point3D::getShowCoordinate()
{
    return m_switch->getValue(1);
}

double Point3D::getCoordinateLineSize()
{
    return m_lineWidth->getWidth();
}

void Point3D::setRadius(double radius)
{
    //std::cout<<"Point3D::setRadius"<<radius<<std::endl;
    m_radius = radius;
    m_sphere->setRadius(m_radius);
    m_shpereShapeDrawable->dirtyDisplayList();
    m_shpereShapeDrawable->dirtyBound();
}

void Point3D::setFineness(double fineness)
{
    m_fineness = fineness;
    m_shpereShapeDrawable->getTessellationHints()->setDetailRatio(m_fineness);
    m_shpereShapeDrawable->dirtyDisplayList();
    m_shpereShapeDrawable->dirtyBound();
}

void Point3D::setCoordinateSize(double coorSize)
{
    //std::cout<<"Point3D::setCoordinateSize"<<m_coordinatePointVector->size()<<std::endl;

    m_coordinateSize = coorSize;

    m_coordinatePointVector->at(1) = osg::Vec3(m_coordinateSize,0,0);
    m_coordinatePointVector->at(3) = osg::Vec3(0,m_coordinateSize,0);
    m_coordinatePointVector->at(5) = osg::Vec3(0,0,m_coordinateSize);

    m_coordinateGeom->dirtyDisplayList();
    m_coordinateGeom->dirtyBound();


}

void Point3D::setShowShpere(bool boolValue)
{

    m_switch->setValue(0, boolValue);
}

void Point3D::setShowCoordinate(bool boolValue)
{
    m_switch->setValue(1, boolValue);

}

void Point3D::setCoordinateLineSize(double doubleValue)
{
    //m_coordinateLineSize = doubleValue;

    m_lineWidth = new osg::LineWidth;
    m_lineWidth ->setWidth(doubleValue);
    m_coordinateGeom->getOrCreateStateSet()->setAttributeAndModes(m_lineWidth.get (),osg::StateAttribute::ON);

}

void Point3D::setIndexInTrajectory3D(int index)
{
    m_indexInTrajectory3D = index;
}

int Point3D::getIndexInTrajectory3D()
{
    return m_indexInTrajectory3D;
}

osg::Vec3 Point3D::getPosition()
{
    osg::Matrix m = this->getMatrix();
    return m.getTrans();
}

void Point3D::buildChildNode()
{
    m_switch = new osg::Switch;
    m_switch->setNodeMask(0xfffffffe);//will not show on objectInspector
    this->addChild(m_switch);

    //add a shpere
    osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
    hints->setDetailRatio(m_fineness);

    m_sphere = new osg::Sphere(osg::Vec3(0.0,0.0,0.0), m_radius);
    m_shpereShapeDrawable = new osg::ShapeDrawable(m_sphere, hints);
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(m_shpereShapeDrawable);
    m_switch->addChild(geode);

    //add coordinate
    m_coordinateGeom = new osg::Geometry;
    m_coordinatePointVector = new osg::Vec3Array;
    osg::ref_ptr<osg::Vec4Array> colorArray = new osg::Vec4Array;
    osg::ref_ptr<osg::Vec3Array> normalArray = new osg::Vec3Array;

    m_coordinateGeom->setVertexArray( m_coordinatePointVector.get() );
    m_coordinateGeom->setColorArray( colorArray.get() );
    m_coordinateGeom->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
    m_coordinateGeom->setNormalArray( normalArray.get() );
    m_coordinateGeom->setNormalBinding( osg::Geometry::BIND_OVERALL );

    normalArray->push_back( osg::Vec3( 0.f,  0.f, 1.f ) );

    //x-axis
    m_coordinatePointVector->push_back(osg::Vec3(0,0,0));
    m_coordinatePointVector->push_back(osg::Vec3(m_coordinateSize, 0, 0));
    colorArray->push_back(osg::Vec4(1,0,0,1));
    colorArray->push_back(osg::Vec4(1,0,0,1));

    //y-axis
    m_coordinatePointVector->push_back(osg::Vec3(0,0,0));
    m_coordinatePointVector->push_back(osg::Vec3(0, m_coordinateSize, 0));
    colorArray->push_back(osg::Vec4(0,1,0,1));
    colorArray->push_back(osg::Vec4(0,1,0,1));

    //z-axis
    m_coordinatePointVector->push_back(osg::Vec3(0,0,0));
    m_coordinatePointVector->push_back(osg::Vec3(0, 0, m_coordinateSize));
    colorArray->push_back(osg::Vec4(0,0,1,1));
    colorArray->push_back(osg::Vec4(0,0,1,1));

    m_coordinateGeom->addPrimitiveSet(new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0,  2 ) );
    m_coordinateGeom->addPrimitiveSet(new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 2,  2 ) );
    m_coordinateGeom->addPrimitiveSet(new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 4,  2 ) );

    //line-size
    m_lineWidth = new osg::LineWidth;
    m_lineWidth ->setWidth(0.1);
    m_coordinateGeom->getOrCreateStateSet()->setAttributeAndModes(m_lineWidth.get (),osg::StateAttribute::ON);

    osg::ref_ptr<osg::Geode> geodeCoor = new osg::Geode;
    geodeCoor->addDrawable(m_coordinateGeom);
    m_switch->addChild(geodeCoor);

    //disable light of coordinate
    osg::StateSet* stateset = geodeCoor->getOrCreateStateSet();
    stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);//这里GL_LIGHTING是系统opengl的头文件GL.h中定义的

}
